#include <string>

#include "Helpers.h"
#include "ProtocolSerializer.h"
#include "Tracer.h"
#include "TraceFormatter.h"




void ProtocolSerializer::SetHeader(ToPSyncMsgHeader h)
{
  ProtocolSerializer& ps = getInstance();
  ps._header = h;
}


ostream& operator<<(ostream& out, const ToPSyncMsgHeader& msgh) 
{
  std::ostringstream   os;  
  std::string          timeStr;

  os << endl << TraceFormatter::TimeHeader(timeStr);
  os << "\nHeader:" << endl;
  os << "\t" << msgh.messageSetId << endl; // cast to print in human readable 
  os << "\t" << (uint16)msgh.messageLength << endl;
  os << "\t" << msgh.messageType << endl;
  os << "\t" << msgh.originatingSequenceNumber << endl;
	os << "\t" << boolalpha << (msgh.endOfMessage!=0) << endl;
	os << "\t" << (uint16)msgh.result << endl;
  os << "\t" << msgh.securityKey << endl;
  os << endl;  
  
  out << os.str();
  return(out);
}

ostream& operator<<(ostream& out, const ProtocolSerializer& ps) {
  return(out);
}




// C wrapper routines
#ifdef __cplusplus
extern "C" {
#endif

void ProtocolSerializerSetHeader(ToPSyncMsgHeader h)
{
  ProtocolSerializer& ps = ProtocolSerializer::getInstance();
  ps.SetHeader(h);
}

void ProtocolSerializerSerialize(void)
{
  ProtocolSerializer& ps = ProtocolSerializer::getInstance();
 // ps.Serialize();


}


#ifdef __cplusplus
}
#endif


static std::ofstream fout;
static bool bSerializerEnabled = false;



void InitSerializer(const char* fname)
{
  fout.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
  try{
    fout.open(fname);
    if(fout.good()){
      bSerializerEnabled = true;
    }
  }
  catch(std::ofstream::failure e){
    cout << "Exception opening/reading file: " << e.what();
  }

}


void SerializeToPSyncMsgHeader(ToPSyncMsgHeader* pMsgHeader)
{
  if(NULL != pMsgHeader){
    if(true == bSerializerEnabled){
      fout.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
      try{
        if (fout.good()){
          fout << (*pMsgHeader);  
          fout.flush();
        }
      }
      catch(std::ofstream::failure e){
        cout << "Exception opening/reading file: " << e.what();
      }
    }
  }
}

void SerializeToPSyncMsgHeaderBinData(const uint8* dataPtr, uint8 len)
{
  if(dataPtr != NULL){
    if(true == bSerializerEnabled){      
      try{ 
        vector<uint8> binVector ( &dataPtr[0], &dataPtr[len] );
        string buff = binary_to_string(binVector);
        buff = HexFormat(buff);
        if (fout.good()){
          fout << buff << endl;    
        }
      }
      catch (const std::exception &exc)
      {
        // catch anything thrown within try block that derives from std::exception
        std::cerr << exc.what();        
        return;
      }     
    }
  }
  
}

void SerializeSpiWriteByte(uint32 address, uint8 data)
{
  
  if(true == bSerializerEnabled){      
    try{
      static char syms[] = "0123456789ABCDEF";
      std::stringstream tmp;
      string direction = string(">>>>>>>>>>");      
      tmp << direction << "\nSpiWriteByte\n\tAddress: 0x";                
      tmp << syms[((address >> 4) & 0xf)] << syms[address & 0xf];
      tmp << "\n\tData: 0x";
      tmp << syms[((data >> 4) & 0xf)] << syms[data & 0xf] << endl;
      fout << tmp.str() << endl; 
    }
    catch (const std::exception &exc){
      // catch anything thrown within try block that derives from std::exception
      std::cerr << exc.what();        
      return;
    }     
  }

}


// eof
